﻿using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Drawing;
//using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
//using System.Runtime.InteropServices;
using System.Text;
using BarCodeDB.Entities;
using BarCodeDB.Services;
using Microsoft.Practices.EnterpriseLibrary.Logging;

/// <summary>
/// Summary description for AppUtil 
/// This class does the actual barcode generation and xml/xslt mapping
/// </summary>
public class BarcodeProcessor
{
    private string _BranchOfficeCityName;       // = "UNIT";
    private string _WorkType;                   // = "WRKT";
    private string _FinancialAdvisorNo;         // = "FANO";
    private string _ClientTaxID;                // = "TXID";
    private string _FormName;                   // = "FORM";
    private string _ClientName;                 // = "CNM1";

    private Guid _FormID;
    private int _MajorVer;
    private int _MinorVer;

    private XmlDocument _xmlDoc;
    private XmlDocument _xmlTargetDoc;
   
    private string _ErrMsg = "";
    private bool _Err = false;


    /// <summary>
    /// Default Constructor
    /// </summary>
    public BarcodeProcessor()
    {
        //Create the Request Document
        _xmlDoc = new XmlDocument();
    }

    #region Properties
    public XmlDocument XMLDoc
    {
        get {return _xmlDoc; }
        set { _xmlDoc = value; }
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <returns></returns>
    public string GetFormName()
    {
        string ret = string.Empty;

        try
        {
            XmlNode formNode = _xmlDoc.GetElementsByTagName("FORM")[0]; 
            if (formNode != null)
            {
                ret = formNode.Attributes["name"].Value;
            }
            else
            {
                ret = "n.a.";
            }
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return ret;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <returns></returns>
    public Guid GetFormID()
    {
        string ret = string.Empty;
        Guid _Guid = Guid.NewGuid() ;

        try
        {
            XmlNode formNode = _xmlDoc.GetElementsByTagName("FORM")[0];
            if (formNode != null)
            {
                ret = formNode.Attributes["file"].Value;
                _Guid = new Guid(ret);
            }
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return _Guid;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <returns></returns>
    public string GetMajorVersionNbr()
    {
        string ret = string.Empty;
        XmlNode formNode = _xmlDoc.GetElementsByTagName("FORM")[0];

        try
        {
            if (formNode != null)
            {
                ret = formNode.Attributes["majv"].Value;
            }
            else
            {
                ret = "-1";
            }
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return ret;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <returns></returns>
    public string GetMinorVersionNbr()
    {
        string ret = string.Empty;
        XmlNode formNode = _xmlDoc.GetElementsByTagName("FORM")[0];
        
        try
        {
            if (formNode != null)
            {
                ret = formNode.Attributes["minv"].Value;
            }
            else
            {
                ret = "-1";
            }
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return ret;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <returns></returns>
    private string GetBranch()
    {
        string ret = string.Empty;

        try
        {
            //XmlNode formNode = xmlDoc.GetElementsByTagName("Branch")[0];
            //if (formNode == null)
            //{
                //Then Lookup by FA Number
                string xFA = GetFinancialAdvisorNbr();
                BarCodeDB.Services.FinancialAdvisorService _FAS = new FinancialAdvisorService();
                BarCodeDB.Entities.FinancialAdvisor _FA =_FAS.GetByFanbr(xFA);
                ret = _FA.Office;
            //}
            //else
            //{
            //    ret = formNode.LastChild.Value;
            //}
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return ret;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="FormID"></param>
    /// <returns></returns>
    private string GetWorkTypeCode(string FormID)
    {
        string sWorkType = "";
        BarCodeDB.Services.FormsWorkTypeService mWorkTypeSvc = new FormsWorkTypeService();
        FormsWorkType frmWorkType = mWorkTypeSvc.GetByFormId(_FormID);
        try
        {
            sWorkType = frmWorkType.WorkType;
            frmWorkType.Dispose();
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return sWorkType;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <returns></returns>
    private string GetFinancialAdvisorNbr()
    {
        string ret = string.Empty;

        try
        {
            XmlNode formNode = this._xmlTargetDoc.GetElementsByTagName("Financial_Advisor")[0];

            if (formNode == null)
            {
                BarCodeDB.Services.FinancialAdvisorService _FAS = new FinancialAdvisorService();
                string _Branch = GetBranch();
                string _Where = "Office=" + _Branch + " AND IsDefault=true";
                BarCodeDB.Entities.TList<FinancialAdvisor> _FAList = _FAS.Find(_Where);

                if (_FAList.Count == 0)
                {
                    // This is a serious error
                    _Err = true;
                    _ErrMsg = "Error - No Financial Advisor provided by the .";
                }
                else
                {
                    ret = _FAList[0].Fanbr;
                }
            }
            else
            {
                ret = formNode.Attributes["number"].Value;
            }
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return ret;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <returns></returns>
    private string GetClientTaxID()
    {
        string ret = string.Empty;

        try
        {
            XmlNode formNode = this._xmlTargetDoc.GetElementsByTagName("SSN")[0];
            ret = formNode.LastChild.Value;

            if (string.IsNullOrEmpty(ret))
            {
                formNode = this._xmlTargetDoc.GetElementsByTagName("TaxID")[0];
                ret = formNode.LastChild.Value;
            }
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return ret;
    }

    private string GetClientName()
    {
        string ret = string.Empty;

        try
        {
            XmlNode formNode = this._xmlTargetDoc.GetElementsByTagName("Name")[0];
            ret = formNode.LastChild.Value;
        }
        catch (Exception se)
        {
            LogError(se.Message);
        }

        return ret;
    }
    #endregion

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlNode"></param>
    /// <returns></returns>
    private void GetTargetData()
    {
        _FinancialAdvisorNo = "FANO" + GetFinancialAdvisorNbr();
        _BranchOfficeCityName = "UNIT" + GetBranch();
        _ClientName = "CNM1" + GetClientName();
        _ClientTaxID = "TXID" + GetClientTaxID();
        _FormName = "FORM" + _FormName;
        _WorkType = "WRKT" + GetWorkTypeCode(_FormID.ToString());
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlDoc"></param>
    /// <param name="idx"></param>
    /// <returns></returns>
    //private XmlNode GetXmlNodeByIDX(XmlDocument xmlDoc, int idx)
    //{
    //    XmlNode ret = null;

    //    XmlNodeList nl = xmlDoc.GetElementsByTagName("Tbox");
    //    foreach (XmlNode node in nl)
    //    {
    //        string strIDX = GetAttributeValue(node, "idx");
    //        if (strIDX == idx.ToString())
    //        {
    //            ret = node;
    //            break;
    //        }
    //    }
    //
    //    return ret;
    //}

    /// <summary>
    /// 
    /// </summary>
    /// <param name="node"></param>
    /// <param name="attributeName"></param>
    /// <returns></returns>
    //private string GetAttributeValue(XmlNode node, string attributeName)
    //{
    //    string ret = string.Empty;
    //    if (null != node && false == string.IsNullOrEmpty(attributeName))
    //    {
    //        foreach (XmlAttribute att in node.Attributes)
    //        {
    //            if (att.Name == attributeName)
    //            {
    //                ret = att.Value;
    //                break;
    //            }
    //        }
    //    }
    //
    //    return ret;
    //}

    /// <summary>
    /// Get string to create barcode.
    /// </summary>
    /// <param name="formXml"></param>
    /// <param name="formName"></param>
    /// <returns></returns>
    public string GetBarcodeData()
    {
        string ret = string.Empty;
        StringBuilder sb = new StringBuilder();

        sb.Append("*");
        sb.Append(_BranchOfficeCityName + "%$");
        sb.Append(_WorkType + "%$");
        sb.Append(_FinancialAdvisorNo + "%$");
        sb.Append(_ClientTaxID + "%$");
        sb.Append(_FormName + "%$");
        sb.Append(_ClientName + "*");

        ret = sb.ToString();
        return ret;
    }

    /// <summary>
    /// Preform the Actual XSLT Transformation here
    /// </summary>
    /// <param name="formID"></param>
    private string PreformMapping(string _formName, string _formID, string FilDropPath)
    {
        int k = _MajorVer;
        int j = _MinorVer;

        BarCodeDB.Services.LaserAppMapsService _LaFormsService = new BarCodeDB.Services.LaserAppMapsService();
        LaserAppMaps _MyLaFormMap = _LaFormsService.GetByFormIdMajorVerMinorVer(_FormID, k, j);

        if (_MyLaFormMap == null)
            return "";

        //Load Map 
        System.Xml.XmlDocument _stylesheet = new XmlDocument();
        _stylesheet.LoadXml(_MyLaFormMap.FormXml);

        string sXsltPath = FilDropPath;
        sXsltPath = sXsltPath + _formName + ".xslt";

        _stylesheet.Save(sXsltPath);

        XPathNavigator _xNav = _xmlDoc.CreateNavigator();
        XslCompiledTransform _xcTrans = new XslCompiledTransform();

        _xcTrans.Load(sXsltPath);

        XmlWriterSettings _Settings = new XmlWriterSettings();
        _Settings.Encoding = System.Text.Encoding.UTF8;
        _Settings.Indent = true;
        _Settings.NewLineHandling = NewLineHandling.None;

        MemoryStream ms = new MemoryStream();
        XmlWriter results = XmlTextWriter.Create(ms, _Settings);
        string temp = "";

        try        
        {
            _xcTrans.Transform(_xNav, results);

            Byte[] _ByteArray = ms.GetBuffer();

            for (int i = 3; i < _ByteArray.Length; i++)
            {
                temp = temp + (Convert.ToChar(_ByteArray[i]));
            }
        }
        catch (SystemException se)
        {
            LogError(se.Message);
            throw se;
        }
        finally
        {
            _LaFormsService = null;
            _MyLaFormMap.Dispose();
        }

        return temp.ToString();
    }

    /// <summary>
    /// This returns data to LaserApp, it also positions the bmp on the form
    /// </summary>
    /// <param name="FormID"></param>
    /// <returns></returns>
    private string PackageTargetData(string FormID, string BarCodeString)
    {
        StringBuilder result =  new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
         
        result.Append("<LARESPMSG xmlns=\"http://www.laserapp.com\" ");
        if (_Err)
        {
            result.Append("type=\"0\" confurl=\"\" msgtext=\"" + _ErrMsg + "\" closeaction=\"0\" disablepost=\"1\">");
        }
        else
        {
            result.Append("type=\"2\" confurl=\"\" msgtext=\"Form - has been barcoded on page 1.\" closeaction=\"0\" disablepost=\"1\">");
        }
        result.Append("<BarCode form=\"{" + FormID + "}\"" );
        result.Append(" page=\"1\" x=\"1050\" y=\"150\" ImgType=\"BMP\">" + BarCodeString + "</BarCode>");
        result.Append("</LARESPMSG>");
        return result.ToString();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="xmlText"></param>
    /// <param name="FileDropPath"></param>
    /// <returns></returns>
    public string BarCodeGenerator(string xmlText, string FileDropPath)
    {
        string barcodeString = "";

        _Err = false;
        BarCodeDB.Entities.RequestLog _newRequestLog = null;

        try
        {
            _xmlDoc.LoadXml(xmlText);

            _FormName = GetFormName();
            _FormID = GetFormID();

            _newRequestLog = new RequestLog();

            _newRequestLog.FormId = _FormID;
            _MajorVer = Convert.ToInt32(GetMajorVersionNbr());
            _newRequestLog.FormMajv = _MajorVer;
            _MinorVer = Convert.ToInt32(GetMinorVersionNbr());
            _newRequestLog.FormMinv = _MinorVer;
            _newRequestLog.DateTimeStamp = DateTime.Now;

            LogHttpRequest(_newRequestLog);

            string sTargetData = PreformMapping(_FormName, _FormID.ToString(), FileDropPath);

            if (sTargetData != "")
            {
                _xmlTargetDoc = new XmlDocument();
                _xmlTargetDoc.LoadXml(sTargetData);

                GetTargetData();
                barcodeString = GetBarcodeData();

                System.Drawing.Image bcImage = AppUtil.GetBarcodeImage(barcodeString);
                barcodeString = AppUtil.ConvertImageToBase64String(bcImage, ImageFormat.Bmp);
                //TargetData = null;
            }
        }
        catch (SystemException se)
        {
            LogError(se.Message);
        }
        finally
        {
            _newRequestLog.Dispose();
        }

        return PackageTargetData(_FormID.ToString(), barcodeString);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="errMsg"></param>
    private void LogError(string errMsg)
    {
        LogEntry _LE = new LogEntry();
        _LE.Message = errMsg;
        _LE.TimeStamp = DateTime.Now;
        _LE.Categories.Add("Exceptions");
        _LE.Priority = 1;
        _LE.Severity = System.Diagnostics.TraceEventType.Error;

        Logger.Write(_LE);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="requestLog"></param>
    /// <returns></returns>
    public bool LogHttpRequest(BarCodeDB.Entities.RequestLog requestLog)
    {
        BarCodeDB.Services.RequestLogService _RLS = new RequestLogService();

        return _RLS.Insert(requestLog);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="FormID"></param>
    /// <param name="ErrMsg"></param>
    /// <returns></returns>
    public string LaserAppErrorResponce(string FormID, string ErrMsg)
    {
        StringBuilder result = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        string sBuff = FormID;
        if (string.IsNullOrEmpty(sBuff))
        {
            sBuff = "BA46D162-AE00-44FC-B534-CF6E27A831A7";
        }

        _ErrMsg = _ErrMsg + " " + ErrMsg;

        result.Append("<LARESPMSG xmlns=\"http://www.laserapp.com\" ");
        result.Append("type=\"0\" confurl=\"\" msgtext=\"" + _ErrMsg + "\" closeaction=\"0\" disablepost=\"1\">");
        result.Append("<BarCode form=\"{" + sBuff + "}\"");
        result.Append(" page=\"1\" x=\"1750\" y=\"20\" ImgType=\"BMP\">" + "</BarCode>");
        result.Append("</LARESPMSG>");
        return result.ToString();
    }
}
